package com.bosssoft.platform.fasttcc.rpc.filter.impl;

import com.bosssoft.platform.fasttcc.TccTransaction;
import com.bosssoft.platform.fasttcc.Xid;
import com.jfireframework.baseutil.TRACEID;
import com.jfireframework.baseutil.uniqueid.SpringId;
import com.jfireframework.baseutil.uniqueid.Uid;
import com.bosssoft.platform.fasttcc.TccTransactionManager;
import com.bosssoft.platform.fasttcc.rpc.command.TccMethodCallCommand;
import com.bosssoft.platform.fasttcc.rpc.filter.RpcFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DefaultRpcFilter implements RpcFilter
{
    private static final Logger                LOGGER = LoggerFactory.getLogger(DefaultRpcFilter.class);
    private              TccTransactionManager transactionManager;
    private              Uid                   uid    = SpringId.getInstance();

    @Override
    public TccMethodCallCommand beforeSendRequest(String remoteIdentifier)
    {
        TccTransaction tccTransaction = transactionManager.getCurrentTccTransaction();
        if (tccTransaction == null)
        {
            LOGGER.debug("traceId:{} 当前不存在TCC事务，不需要进行RPC拦截", TRACEID.currentTraceId());
            return null;
        }
        if (tccTransaction.getState() != TccTransaction.ACTIVE)
        {
            LOGGER.debug("traceId:{} 当前事务的状态不是激活状态，不需要拦截。当前状态:{}", TRACEID.currentTraceId(), tccTransaction.getState());
        }
        String traceId = TRACEID.currentTraceId();
        LOGGER.debug("traceId:{} 当前处于TCC事务中，准备注册远端资源", traceId);
        transactionManager.registerRemoteResource(tccTransaction, remoteIdentifier);
        Xid                  xid     = tccTransaction.getXid();
        TccMethodCallCommand command = new TccMethodCallCommand();
        command.setXid(xid);
        command.setNodeIdentifier(transactionManager.getIdentifier());
        command.setCallId(uid.generate());
        LOGGER.debug("traceId:{} 本次远端调用，xid:{},callId:{},nodeIdentifier:{}", traceId, command.getXid(), command.getCallId(), command.getNodeIdentifier());
        return command;
    }

    public void setTransactionManager(TccTransactionManager transactionManager)
    {
        this.transactionManager = transactionManager;
    }
}
